<template>
  <div v-if="show" class="file-preview-overlay" @click.self="closePreview">
    <div class="file-preview-container">
      <div class="preview-header">
        <h3>{{ file.file_name }}</h3>
        <button class="close-btn" @click="closePreview">&times;</button>
      </div>
      
      <div class="preview-content">
        <!-- 图片预览 -->
        <div v-if="isImage" class="image-preview">
          <img :src="file.url" :alt="file.file_name" />
        </div>
        
        <!-- 视频预览 -->
        <div v-else-if="isVideo" class="video-preview">
          <video controls>
            <source :src="file.url" :type="`video/${file.type}`">
            您的浏览器不支持视频预览
          </video>
        </div>
        
        <!-- 音频预览 -->
        <div v-else-if="isAudio" class="audio-preview">
          <audio controls>
            <source :src="file.url" :type="`audio/${file.type}`">
            您的浏览器不支持音频预览
          </audio>
        </div>
        
        <!-- PDF预览 -->
        <div v-else-if="isPdf" class="pdf-preview">
          <iframe :src="file.url" frameborder="0"></iframe>
        </div>
        
        <!-- 文本预览（如果支持） -->
        <div v-else-if="isText" class="text-preview">
          <div v-if="textContent" class="text-content">
            <pre>{{ textContent }}</pre>
          </div>
          <div v-else class="loading-text">
            正在加载文本内容...
          </div>
        </div>
        
        <!-- 不支持预览的文件类型 -->
        <div v-else class="unsupported-preview">
          <div class="file-icon" :class="getFileIconClass(file.type)"></div>
          <p>无法预览此类型的文件 ({{ file.type }})</p>
          <button class="download-btn" @click="downloadFile">
            下载文件
          </button>
        </div>
      </div>
      
      <div class="preview-footer">
        <div class="file-info">
          <span>类型: {{ file.type }}</span>
          <span>大小: {{ formatFileSize(file.size) }}</span>
          <span>上传时间: {{ file.create_time }}</span>
        </div>
        <button class="download-btn" @click="downloadFile">
          下载
        </button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue';

// 接收属性
const props = defineProps({
  show: {
    type: Boolean,
    default: false
  },
  file: {
    type: Object,
    default: () => ({})
  }
});

// 发出事件
const emit = defineEmits(['close']);

// 状态变量
const textContent = ref(null);

// 关闭预览
const closePreview = () => {
  emit('close');
};

// 下载文件
const downloadFile = () => {
  const a = document.createElement('a');
  a.href = props.file.url;
  a.download = props.file.file_name;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
};

// 文件类型判断
const isImage = computed(() => {
  const imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg'];
  return imageTypes.includes(props.file.type?.toLowerCase());
});

const isVideo = computed(() => {
  const videoTypes = ['mp4', 'webm', 'ogg', 'mov', 'avi'];
  return videoTypes.includes(props.file.type?.toLowerCase());
});

const isAudio = computed(() => {
  const audioTypes = ['mp3', 'wav', 'ogg', 'aac'];
  return audioTypes.includes(props.file.type?.toLowerCase());
});

const isPdf = computed(() => {
  return props.file.type?.toLowerCase() === 'pdf';
});

const isText = computed(() => {
  const textTypes = ['txt', 'json', 'xml', 'md', 'html', 'css', 'js', 'ts', 'csv'];
  return textTypes.includes(props.file.type?.toLowerCase());
});

// 加载文本内容
const loadTextContent = async () => {
  if (!isText.value || !props.file.url) return;
  
  try {
    const response = await fetch(props.file.url);
    if (!response.ok) throw new Error('无法加载文本内容');
    
    const text = await response.text();
    textContent.value = text;
  } catch (error) {
    console.error('加载文本内容出错:', error);
    textContent.value = '无法加载文本内容';
  }
};

// 获取文件图标类
const getFileIconClass = (fileType) => {
  const typeMap = {
    'png': 'image-icon',
    'jpg': 'image-icon',
    'jpeg': 'image-icon',
    'gif': 'image-icon',
    'mp4': 'video-icon',
    'avi': 'video-icon',
    'mov': 'video-icon',
    'mp3': 'audio-icon',
    'wav': 'audio-icon',
    'pdf': 'pdf-icon',
    'doc': 'doc-icon',
    'docx': 'doc-icon',
    'xls': 'excel-icon',
    'xlsx': 'excel-icon',
    'txt': 'text-icon',
    'zip': 'archive-icon',
    'rar': 'archive-icon',
    'dll': 'binary-icon'
  };
  
  return typeMap[fileType?.toLowerCase()] || 'file-icon';
};

// 格式化文件大小
const formatFileSize = (bytes) => {
  if (bytes === 0 || !bytes) return '0 B';
  
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};

// 监听显示状态
watch(() => props.show, (newVal) => {
  if (newVal && isText.value) {
    loadTextContent();
  }
});

// 组件挂载时
onMounted(() => {
  if (props.show && isText.value) {
    loadTextContent();
  }
});
</script>

<style scoped>
.file-preview-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.7);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.file-preview-container {
  background-color: white;
  border-radius: 8px;
  width: 90%;
  max-width: 1000px;
  height: 90%;
  max-height: 800px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
  animation: zoom-in 0.3s ease-out;
}

@keyframes zoom-in {
  from {
    transform: scale(0.9);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}

.preview-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px 20px;
  background-color: #f5f5f5;
  border-bottom: 1px solid #eee;
}

.preview-header h3 {
  margin: 0;
  font-size: 18px;
  color: #333;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 90%;
}

.close-btn {
  background: none;
  border: none;
  font-size: 24px;
  cursor: pointer;
  color: #666;
  padding: 0;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
}

.close-btn:hover {
  background-color: #e0e0e0;
}

.preview-content {
  flex: 1;
  overflow: auto;
  padding: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #f9f9f9;
}

.image-preview {
  max-width: 100%;
  max-height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.image-preview img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.video-preview {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.video-preview video {
  max-width: 100%;
  max-height: 100%;
}

.audio-preview {
  width: 100%;
  padding: 20px;
}

.audio-preview audio {
  width: 100%;
}

.pdf-preview {
  width: 100%;
  height: 100%;
}

.pdf-preview iframe {
  width: 100%;
  height: 100%;
  border: none;
}

.text-preview {
  width: 100%;
  height: 100%;
  overflow: auto;
}

.text-content {
  background-color: white;
  padding: 15px;
  border-radius: 4px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.text-content pre {
  margin: 0;
  white-space: pre-wrap;
  word-wrap: break-word;
  font-family: monospace;
  font-size: 14px;
  line-height: 1.5;
}

.loading-text {
  text-align: center;
  padding: 20px;
  color: #666;
}

.unsupported-preview {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 30px;
  text-align: center;
}

.unsupported-preview .file-icon {
  width: 80px;
  height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  margin-bottom: 20px;
  font-size: 40px;
  color: white;
}

.unsupported-preview p {
  margin-bottom: 20px;
  color: #666;
}

.preview-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px 20px;
  background-color: #f5f5f5;
  border-top: 1px solid #eee;
}

.file-info {
  display: flex;
  gap: 20px;
  color: #666;
  font-size: 14px;
}

.download-btn {
  padding: 8px 15px;
  background-color: #1e88e5;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
}

.download-btn:hover {
  background-color: #1976d2;
}

/* 文件图标样式 */
.image-icon { background-color: #81c784; }
.video-icon { background-color: #64b5f6; }
.audio-icon { background-color: #9575cd; }
.pdf-icon { background-color: #e57373; }
.doc-icon { background-color: #4fc3f7; }
.excel-icon { background-color: #66bb6a; }
.text-icon { background-color: #9e9e9e; }
.archive-icon { background-color: #ffb74d; }
.binary-icon { background-color: #ba68c8; }
.file-icon { background-color: #9e9e9e; }

@media (max-width: 768px) {
  .file-preview-container {
    width: 95%;
    height: 95%;
  }
  
  .file-info {
    flex-direction: column;
    gap: 5px;
  }
}
</style> 